#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <libavformat/avformat.h>
#include <libavutil/imgutils.h>
#include <libavutil/opt.h>
#include <libavcodec/avcodec.h>

int get_video_thumbnail(const char *input_filename, const char *output_filename, int width, int height) {
    av_register_all();

    AVFormatContext *format_ctx = NULL;
    avformat_open_input(&format_ctx, input_filename, NULL, NULL);
    avformat_find_stream_info(format_ctx, NULL);

    int video_stream_index = -1;
    for (int i = 0; i < format_ctx->nb_streams; i++) {
        if (format_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            video_stream_index = i;
            break;
        }
    }

    AVCodec *codec = avcodec_find_decoder(format_ctx->streams[video_stream_index]->codecpar->codec_id);
    AVCodecContext *codec_ctx = avcodec_alloc_context3(codec);
    avcodec_parameters_to_context(codec_ctx, format_ctx->streams[video_stream_index]->codecpar);
    avcodec_open2(codec_ctx, codec, NULL);

    AVPacket packet;
    av_init_packet(&packet);
    packet.data = NULL;
    packet.size = 0;

    AVFrame *frame = av_frame_alloc();
    int got_frame;

    while (av_read_frame(format_ctx, &packet) >= 0) {
        if (packet.stream_index == video_stream_index) {
            avcodec_decode_video2(codec_ctx, frame, &got_frame, &packet);
            if (got_frame) {
                AVFrame *scaled_frame = av_frame_alloc();
                struct SwsContext *sws_ctx = sws_getContext(codec_ctx->width, codec_ctx->height, codec_ctx->pix_fmt,
                                                            width, height, AV_PIX_FMT_RGB24, SWS_BILINEAR, NULL, NULL, NULL);
                av_image_alloc(scaled_frame->data, scaled_frame->linesize, width, height, AV_PIX_FMT_RGB24, 1);
                sws_scale(sws_ctx, (const uint8_t *const *) frame->data, frame->linesize, 0, codec_ctx->height,
                          scaled_frame->data, scaled_frame->linesize);
                FILE *file = fopen(output_filename, "wb");
                fwrite(scaled_frame->data[0], 1, width * height * 3, file);
                fclose(file);
                av_freep(&scaled_frame->data[0]);
                av_frame_free(&scaled_frame);
                sws_freeContext(sws_ctx);
            }
        }
        av_packet_unref(&packet);
    }

    av_frame_free(&frame);
    avcodec_close(codec_ctx);
    avformat_close_input(&format_ctx);

    return 0;
}